/*	ObservationData.cpp
	Copyright 2012 Nico Marrero
	This file is part of SCRNOBS.

    SCRNOBS is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SCRNOBS is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with SCRNOBS.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __OBSERVATION_DATA_HEADER__
#define __OBSERVATION_DATA_HEADER__

#include <wx/wx.h>
#include <wx/xml/xml.h>
#include <wx/dynarray.h>
#include <wx/txtstrm.h>
#include <wx/datetime.h>
#include <wx/progdlg.h>
#include <wx/arrimpl.cpp>
#include <wxwidgets/wxExposure.h>

#define DECLARE(type, name) protected: type m_ ## name;
#define SET(type, name, ...) public: void Set##name(type val){if (this->m_ ## name != val){this->m_ ## name = val; __VA_ARGS__}}
#define GET(type, name) public: type Get##name(void){return(this->m_ ## name);}
#define DECLARE_GET_SET(type, name, ...) \
	DECLARE(type, name) \
	SET(type, name, __VA_ARGS__)		\
	GET(type, name)		\

typedef enum {EST, EDT} Timezone;
typedef enum {MON, TUE, WED, THU, FRI, SAT, SUN} DayOfWeek;
extern wxString TimezoneStr[];
extern wxString DayOfWeekStr[];

class ObservationData;
WX_DECLARE_HASH_MAP(int, ObservationData*, wxIntegerHash, wxIntegerEqual, _ObservationDataIDHash);
class ObservationDataIDHash : public _ObservationDataIDHash {public: ~ObservationDataIDHash(){this->Destroy();} void Destroy();};
class ObservationData: virtual public Exposure
{
public:
	ObservationData();
	~ObservationData();

	static void SetDataChanged(void);
	static bool GetDataChanged(void);
	static unsigned int GetDataCount(void);
	static wxString* GetDataIDs(void);
	static int* GetDataIndices(void);
	static int* GetSortedDataIndices(void);
	static ObservationData *FindDataByID(wxString DataID);
	static ObservationData *FindDataByIndex(unsigned int index);
	static int FindIndex(ObservationData* data);
	static void SaveAllDataXML(wxXmlNode *Root);
	static bool LoadAllDataXML(wxXmlNode* Root);
	static wxTextOutputStream& ExportAllDataCSV(wxTextOutputStream& strm);
	static wxTextOutputStream& ExportAllDataSCRNOBS(wxTextOutputStream& strm);
	wxXmlNode* SaveXML();
	bool LoadXML(wxXmlNode* CurrentNode);
	wxTextOutputStream& ExportCSV(wxTextOutputStream& strm);
	wxTextOutputStream& ExportSCRNOBS(wxTextOutputStream& strm);
	wxString GetDataID();
	wxString GetFormattedDate();
	wxString GetFormattedTime();
	wxString GetSCRNOBSFormattedDate();
	wxString GetSCRNOBSFormattedTime();

	//Header
	DECLARE_GET_SET(wxString, Date, this->m_Date = this->GetFormattedDate(); this->SetDataChanged();)
	DECLARE_GET_SET(wxString, Time, this->m_Time = this->GetFormattedTime(); this->SetDataChanged();)
	DECLARE_GET_SET(DayOfWeek, DayOfWeek)
	DECLARE_GET_SET(Timezone, Timezone)
	DECLARE_GET_SET(wxString, Observer, this->SetDataChanged();)
	DECLARE_GET_SET(wxString, Notes)
	//Current Values
	DECLARE_GET_SET(float, Temp)
	DECLARE_GET_SET(float, DewPoint)
	DECLARE_GET_SET(float, PresChg3hr)
	DECLARE_GET_SET(float, StationPres)
	DECLARE_GET_SET(float, SeaLvlPres)
	DECLARE_GET_SET(float, WindSpeed)
	DECLARE_GET_SET(float, WindDir)
	DECLARE_GET_SET(int, CloudCover)
	DECLARE_GET_SET(wxString, CloudType)
	//24 Hr Summary
	DECLARE_GET_SET(float, MaxTemp_8to8)
	DECLARE_GET_SET(float, MaxTemp_12to12)
	DECLARE_GET_SET(float, MinTemp_8to8)
	DECLARE_GET_SET(float, MinTemp_12to12)
	DECLARE_GET_SET(float, HDD_8to8)
	DECLARE_GET_SET(float, HDD_12to12)
	DECLARE_GET_SET(float, SolarRad)
	DECLARE_GET_SET(float, Precip)
	DECLARE_GET_SET(float, SnowFall)
	DECLARE_GET_SET(float, SnowDepth)
	DECLARE_GET_SET(float, AvgWindSpeed)

protected:
	static ObservationDataIDHash sm_data;
	static bool sm_changed;

	DECLARE_EXPOSURE_TABLE();
};

#endif

